home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Panorama
/
Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].zip
/
Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].adf
/
HackBench
/
hbicon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-07-14
|
21KB
|
683 lines
/****************************************************************
/* *
/* HackBench - Part 2 of 4 - hbicon.c - Icon Routines *
/* *
/* Copyright (C) 1987 by Bill Kinnersley *
/* CS Dept, Washington State Univ, Pullman, WA 99164 *
/* *
/* Permission granted to redistribute this program *
/* provided the copyright notice remains intact. *
/* May not be used as part of any commercial product. *
/* *
/****************************************************************/
#include "hb.h"
extern struct DosInfo *rnInfo;
extern struct MsgPort *IDCMPPort, WBPort;
extern long IDCMPBit, WBBit;
extern USHORT x_ptr[];
extern struct Gadget
vs_gad, hs_gad, ren_gad, up_gad, dm_gad, lm_gad, rm_gad;
extern struct PropInfo hs_knob, vs_knob;
extern struct Rectangle rect;
extern char *type[], *title;
extern short wbFlags, toolsRunning;
extern struct List selObjs, wbObjs, utilObjs;
extern int drawobj(), clearobj(), compobj(), openobj(), closeobj();
extern char *rindex();
struct MyWBObject *lastObj, *hitObj, *hitWinObj, *findObj(), *makeWbObj();
struct Window *wbWin, *oldWin, *curWin, *hitWin, *errWin;
struct IntuiMessage saveMsg;
struct Layer_Info *li;
ULONG downSecs, downMicros, upSecs, upMicros;
short oldX, oldY, dblclik, debug=FALSE;
char buf1[61], buf2[61];
struct DeviceList *vol();
BPTR getlock();
long tooSoon();
main() {
struct Message *msg;
struct WBStartup *wbmsg;
long mask;
BPTR seg;
openAll();
curWin = wbWin; /* Current window is the backdrop */
li = &wbWin->WScreen->LayerInfo;
findDisks();
makeMenu();
OnMenu(wbWin, REDRAW); OnMenu(wbWin, VERS);
avail();
while (1) { /* We have two ports to monitor at once */
mask = Wait(IDCMPBit | WBBit);
if (mask & WBBit) while (msg = GetMsg(WBPort)) {
/* Unload the tool that just exited */
wbmsg = (struct WBStartup *)msg;
if (debug) printf("Unloading\n");
if (seg = wbmsg->sm_Segment) UnLoadSeg(seg);
FreeMem(wbmsg->sm_ArgList,
wbmsg->sm_NumArgs*(long)sizeof(struct WBArg));
FreeMem(msg, (long)sizeof(struct WBStartup));
toolsRunning--;
}
if (mask & IDCMPBit) while (msg = GetMsg(IDCMPPort))
doIDCMP(msg);
}
}
doIDCMP(msg) struct IntuiMessage *msg; {
struct MyWBObject *obj;
struct DeviceList *diDev, *ptr;
char diskName[31];
struct Node *node;
/*stc*/ saveMsg = *msg;
ReplyMsg(msg);
curWin = oldWin = saveMsg.IDCMPWindow;
switch (saveMsg.Class) {
case CLOSEWINDOW :
obj = (struct MyWBObject *)oldWin->UserData;
closeobj(obj);
clearSel();
avail();
break;
case MENUPICK: doMenu(saveMsg.Code); break;
case MOUSEBUTTONS:
switch(saveMsg.Code) {
case SELECTDOWN: doSelDown(); break;
case SELECTUP: doSelUp(); break;
}
break;
case GADGETUP: doGadUp(); break;
case GADGETDOWN: doGadDown(); break;
case DISKINSERTED:
/*Delay(10L);*/ /* May be necessary */
/* Scan the Device List for a Volume that does not
appear on the Master List of WBObjects */
diDev = (struct DeviceList *) BADDR(rnInfo->di_DevInfo);
for (ptr=diDev; ptr; ptr=(struct DeviceList *)
BADDR(ptr->dl_Next)) if (ptr->dl_Type==DLT_VOLUME) {
bs2cs(diskName, ptr->dl_Name);
if (!FindName(&wbObjs, diskName)) break;
}
if (!ptr) break;
instDisk(diskName); /* Make a new disk object */
refresh(wbWin);
break;
case DISKREMOVED:
Delay(10L); /* This does seem to be necessary */
/* For each disk object, check to see if it's still
on the Device List */
diDev = (struct DeviceList *) BADDR(rnInfo->di_DevInfo);
for (node=wbObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
obj = (struct MyWBObject *)node;
if (obj->wo_Type!=WBDISK) continue;
for (ptr=diDev; ptr; ptr=(struct DeviceList *)
BADDR(ptr->dl_Next)) if (ptr->dl_Type==DLT_VOLUME) {
bs2cs(diskName, ptr->dl_Name);
if (strcmp(diskName, obj->wo_Name)==0) break;
}
if (ptr) continue;
clearobj(obj); /* Not found--get rid of it */
deleteobj(obj);
break;
}
refresh(wbWin);
break;
case REFRESHWINDOW:
if (debug)
printf("Window %lx is SIMPLY REFRESHING!\n", curWin);
BeginRefresh(curWin);
refresh(curWin);
EndRefresh(curWin, TRUE);
break;
case NEWSIZE:
reclip(curWin);
resize(curWin);
break;
}
}
clearSel() { /* Purge the Select List */
struct Node *node;
doList(&selObjs, SEL, drawobj, NORM);
while (node = RemHead(&selObjs)) node->ln_Succ = NULL;
/* So we can tell later whether a given object
is still on the List */
lastObj = NULL;
OffMenu(wbWin, OPEN); OffMenu(wbWin, CLOZE);
OffMenu(wbWin, DUP); OffMenu(wbWin, RENAME);
OffMenu(wbWin, INFO); OffMenu(wbWin, INIT);
OffMenu(wbWin, SNAP); OffMenu(wbWin, DISCARD);
}
doOpen() {
struct Node *node;
struct MyWBObject *obj;
/* If there's a tool or project on the Select List, run it.
Otherwise, just open everybody on the List */
for (node=selObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
obj = OBJ(node,SEL);
if (obj->wo_Type==WBTOOL || obj->wo_Type==WBPROJECT)
{run(obj); return;}
}
doList(&selObjs, SEL, openobj);
}
/* doSelDown does three things:
Detects and handles double clicks
Accumulates the extended selection list
Toggles menu items
*/
doSelDown() {
struct MyWBObject *obj;
struct Node *node;
if (errWin) {SetWindowTitles(errWin,-1L,title); errWin=NULL;}
if (obj = findObj(saveMsg.MouseX, saveMsg.MouseY, curWin)) {
/* Hit an icon */
if (dblclik = ((obj==lastObj) && DoubleClick(downSecs,
downMicros, saveMsg.Seconds, saveMsg.Micros))) {
/* Double click */
if (debug) printf("Double click\n");
saveMsg.Seconds -= 20L; /* To prevent triple clicks */
doOpen();
OffMenu(wbWin, OPEN); OnMenu(wbWin, CLOZE);
avail();
}
else { /* Single click so far */
if (debug) printf("Single click\n");
SetPointer(oldWin, x_ptr, 12L, 12L, -6L, -6L);
if (saveMsg.Qualifier & SHIFT) {
/* Extended selection rules out some operations */
OffMenu(wbWin, DUP); OffMenu(wbWin, RENAME);
OffMenu(wbWin, INFO);
}
else {
doList(&selObjs, SEL, drawobj, NORM);
while (node = RemHead(&selObjs))
node->ln_Succ = node->ln_Pred = NULL;
OnMenu(wbWin, DUP); OnMenu(wbWin, RENAME);
OnMenu(wbWin, INFO);
}
OnMenu(wbWin, SNAP);
if (!obj->wo_SelectNode.ln_Succ) /* Not yet selected */
AddHead(&selObjs, &obj->wo_SelectNode);
/* Exec gets confused if a node is in the same list twice */
drawobj(obj, HIGH); /* Highlight it */
/* Did I hit an open drawer? */
if (obj->wo_DrawerData
&& obj->wo_DrawerData->dd_DrawerWin)
{OnMenu(wbWin, CLOZE); OffMenu(wbWin, OPEN);}
/* Either a closed drawer or a tool */
/* Tools can always be opened */
else {OnMenu(wbWin, OPEN); OffMenu(wbWin, CLOZE);}
lastObj = obj; oldX = saveMsg.MouseX; oldY = saveMsg.MouseY;
downSecs = saveMsg.Seconds; downMicros = saveMsg.Micros;
}
}
else clearSel(); /* Didn't hit an icon */
}
doSelUp() {
struct Layer *layer;
struct Window *w;
short dx, dy;
BPTR lock, lock2;
struct MyDrawerData *dd;
if (dblclik) {dblclik = FALSE; return;}
ClearPointer(oldWin);
if (!lastObj) return;
curWin = oldWin;
upSecs = saveMsg.Seconds; upMicros = saveMsg.Micros;
/* Selectup msg is sent back to the window where selectdown occurred,
(oldWin), so we have to search the layers for the real window */
layer = WhichLayer(li, (long)(saveMsg.MouseX + oldWin->LeftEdge),
(long)(saveMsg.MouseY + oldWin->TopEdge));
for (hitWin=wbWin->WScreen->FirstWindow; hitWin;
hitWin=hitWin->NextWindow)
if (hitWin->WLayer==layer) break;
if (!hitWin) return; /* Shouldn't happen */
if (!(hitWin->Flags & WBENCHWINDOW))
{error("That's somebody else's window"); return;}
if (hitWin!=wbWin) if (lastObj->wo_Type==WBDISK)
{error("Disks can't be moved into windows"); return;}
if (lastObj->wo_Type==WBGARBAGE)
if (hitWin!=lastObj->wo_IconWin)
{error("A trashcan must stay in its own window"); return;}
if (lastObj->wo_Type==WBDRAWER)
if (hitWin==lastObj->wo_DrawerData->dd_DrawerWin)
/* You tried to move an icon into its own open window, dodo */
{error("Hey, that's me!"); return;}
hitWinObj = (struct MyWBObject *)hitWin->UserData;
/* hitWinObj may be NULL if hitWin is the backdrop */
dx = saveMsg.MouseX + oldWin->LeftEdge - hitWin->LeftEdge;
dy = saveMsg.MouseY + oldWin->TopEdge - hitWin->TopEdge;
hitObj = findObj(dx, dy, hitWin);
if (debug) printf("SelUp hitObj=%lx hitWin=%lx\n", hitObj, hitWin);
if ((!hitObj) || (hitObj==lastObj))
{moveObj(&selObjs, SEL, dx - oldX, dy - oldY); return;}
/* So from here on we must have hit a new icon */
if (debug) printf("Hit <%s>, a %s\n",
hitObj->wo_Name, type[hitObj->wo_Type]);
switch (hitObj->wo_Type) {
case WBDISK: if (lastObj->wo_Type==WBDISK)
{error("DiskCopy not implemented"); return;}
if (lastObj->wo_Type==WBGARBAGE)
{error("A trashcan must stay in its own window"); return;}
if (hitObj==lastObj->wo_Parent) break;
lock = getlock(lastObj);
if (vol(lock)==vol(hitObj->wo_Lock)) {
/* On same disk--just rename */
strcpy(buf1, lastObj->wo_Name); strcpy(buf2, lastObj->wo_Name);
if (debug) printf("Renaming %lx <%s> to %lx <:%s>\n",
lock, lastObj->wo_Name, hitObj->wo_Lock, lastObj->wo_Name);
strcat(buf1, ".info"); strcat(buf2, ".info");
renBoth(lock, buf1, hitObj->wo_Lock, buf2);
break;
}
/* Otherwise copy to another disk--not implemented */
if (debug) printf("I should copy %lx <%s> to %lx <%s:>\n",
lock, lastObj->wo_Name, hitObj->wo_Lock, hitObj->wo_Name);
return;
case WBDRAWER:
case WBGARBAGE: /* Hit a drawer icon */
if (hitObj==lastObj->wo_Parent) break;
if (lastObj->wo_Type==WBDISK) if (hitWin!=wbWin)
{error("Can't move a disk into a drawer"); return;}
if (lastObj->wo_Type==WBGARBAGE)
{error("A trashcan must stay in its own window"); return;}
strcpy(buf1, lastObj->wo_Name); strcpy(buf2, hitObj->wo_Name);
strcat(buf2, "/"); strcat(buf2, lastObj->wo_Name);
lock = getlock(lastObj); lock2 = getlock(hitObj);
if (debug) printf("Renaming %lx <%s> to %lx <%s>\n",
lock, buf1, lock2, buf2);
strcat(buf1, ".info"); strcat(buf2, ".info");
renBoth(lock, buf1, lock2, buf2);
break;
default: /* Just let the icons overlap */
moveObj(&selObjs, SEL, dx-oldX, dy-oldY);
return;
}
goAway();
doResize();
}
goAway() { /* Do move from one window to another */
struct MyDrawerData *dd;
struct Window *w;
mark(lastObj->wo_IconWin);
clearobj(lastObj);
Remove(&lastObj->wo_Siblings);
lastObj->wo_Siblings.ln_Succ = NULL;
dd = hitObj->wo_DrawerData;
if (w=dd->dd_DrawerWin) { /* Destination window open */
AddHead(&dd->dd_Children, &lastObj->wo_Siblings);
lastObj->wo_Parent = hitObj;
lastObj->wo_IconWin = w;
mark(w);
Remove(lastObj); AddTail(&wbObjs, lastObj);
/* Rearrange, so that refresh() draws it last (on top) */
}
else deleteobj(lastObj);
}
moveObj(list, off, x, y)
struct List *list; long off; short x, y; {
struct Node *node;
struct MyWBObject *obj, *iconWinObj;
struct Window *w;
struct MyDrawerData *dd;
char *p;
BPTR lock, lock2;
mark(hitWin);
hitWinObj = (struct MyWBObject *)hitWin->UserData;
if (tooSoon()) return; /* If selup too soon, ignore */
doList(list, off, clearobj);
for (node=list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
obj = OBJ(node,off);
if (debug)
printf("moveObj: %lx (%d %d) by (%d %d) from %lx to %lx\n",
obj, obj->wo_Gadget.LeftEdge, obj->wo_Gadget.TopEdge,
x, y, obj->wo_IconWin, hitWin);
iconWinObj = (struct MyWBObject *)obj->wo_IconWin->UserData;
mark(obj->wo_IconWin);
if (obj->wo_IconWin!=hitWin) { /* Changing windows */
/* Adjust the virtual coordinates */
if (obj->wo_IconWin!=wbWin) {
dd = iconWinObj->wo_DrawerData;
obj->wo_CurrentX -= dd->dd_CurrentX;
obj->wo_CurrentY -= dd->dd_CurrentY;
}
if (hitWin!=wbWin) {
dd = hitWinObj->wo_DrawerData;
obj->wo_CurrentX += dd->dd_CurrentX;
obj->wo_CurrentY += dd->dd_CurrentY;
}
if (hitWin==wbWin) { /* To the backdrop */
/* A backdrop icon needs its very own lock,
in case its parent's drawer is later closed */
obj->wo_Lock = DupLock(obj->wo_Parent->
wo_DrawerData->dd_Lock);
if (debug) printf("Duplicate lock: <%s> %lx\n",
obj->wo_Name, obj->wo_Lock);
}
else if (hitWinObj==obj->wo_Parent) {
/* Into the open drawer of my parent */
if (debug) printf("Oh Lawdy, I'se home--home at las'!\n");
/* I don't need my lock any more */
if (obj->wo_Lock) { /* Coming from the backdrop */
if (debug) printf("Unlocking <%s>: %lx\n",
obj->wo_Name, obj->wo_Lock);
UnLock(obj->wo_Lock);
obj->wo_Lock = NULL;
}
}
else { /* Into some other open drawer */
lock = getlock(obj);
lock2 = hitWinObj->wo_DrawerData->dd_Lock;
if (vol(lock)==vol(lock2)) {
strcpy(buf1, obj->wo_Name); strcpy(buf2, obj->wo_Name);
if (debug) printf("Renaming %lx <%s> to %lx <%s>\n",
lock, buf1, lock2, buf2);
strcat(buf1, ".info"); strcat(buf2, ".info");
renBoth(lock, buf1, lock2, buf2);
}
else {
bs2cs(buf2, vol(lock2)->dl_Name);
if (debug) printf("I should copy %lx <%s> to %lx <%s/%s> on <%s:>\n",
lock, obj->wo_Name, lock2,
hitWinObj->wo_Name, obj->wo_Name, buf2);
}
Remove(&obj->wo_Siblings);
AddHead(&dd->dd_Children, &obj->wo_Siblings);
obj->wo_Parent = hitWinObj;
}
obj->wo_IconWin = hitWin;
}
obj->wo_CurrentX += x;
obj->wo_CurrentY += y;
Remove(obj); AddTail(&wbObjs, obj);
/* So that refresh() draws it last (on top) */
}
doList(list, off, drawobj, HIGH);
doResize();
}
mark(w) struct Window *w; { /* Mark window for later resizing */
if (w!=wbWin)
((struct MyWBObject *)w->UserData)->wo_Flags |= RESIZE;
else wbFlags |= RESIZE;
}
doResize() {
struct Node *node;
struct MyWBObject *obj;
struct Window *w;
for (node=wbObjs.lh_Head; node->ln_Succ; node=node->ln_Succ) {
obj = (struct MyWBObject *)node;
if (obj->wo_Flags & RESIZE) {
w = obj->wo_DrawerData->dd_DrawerWin;
resize(w);
refresh(w);
obj->wo_Flags &= ~RESIZE;
}
}
if (wbFlags & RESIZE) {
/* It might be worth having a fake object whose drawer is
the backdrop, but all we really need is the Flags field */
refresh(wbWin);
wbFlags &= ~RESIZE;
}
}
doGadDown () {
USHORT gid;
struct MyDrawerData *dd;
short shift;
long pos;
gid = ((struct Gadget *)saveMsg.IAddress)->GadgetID;
dd = ((struct MyWBObject *)oldWin->UserData)->wo_DrawerData;
shift = saveMsg.Qualifier & SHIFT;
lastObj = NULL;
switch (gid) {
case GID_VERTSCROLL: case GID_HORIZSCROLL: return;
case GID_LEFTSCROLL: pos = (ULONG)dd->dd_HorizProp.HorizPot;
dd->dd_CurrentX -= shift ? 1 : 20;
break;
case GID_RIGHTSCROLL: pos = (ULONG)dd->dd_HorizProp.HorizPot;
dd->dd_CurrentX += shift ? 1 : 20;
break;
case GID_UPSCROLL: pos = (ULONG)dd->dd_VertProp.VertPot;
dd->dd_CurrentY -= shift ? 1 : 10;
break;
case GID_DOWNSCROLL: pos = (ULONG)dd->dd_VertProp.VertPot;
dd->dd_CurrentY += shift ? 1 : 10;
break;
}
resize(oldWin);
SetRast(oldWin->RPort, 0L);
refresh(oldWin);
}
doGadUp() {
USHORT gid;
struct MyDrawerData *dd;
long pos;
gid = ((struct Gadget *)saveMsg.IAddress)->GadgetID;
dd = ((struct MyWBObject *)oldWin->UserData)->wo_DrawerData;
switch (gid) {
case GID_HORIZSCROLL: /* I don't understand this either */
pos = (ULONG)dd->dd_HorizProp.HorizPot;
dd->dd_CurrentX = dd->dd_MinX + (pos *
(MAX(dd->dd_CurrentX, dd->dd_MaxX - (oldWin->Width-14L))
- MIN(dd->dd_CurrentX, dd->dd_MinX)) ) / MAXBODY;
break;
case GID_VERTSCROLL:
pos = (ULONG)dd->dd_VertProp.VertPot;
dd->dd_CurrentY = dd->dd_MinY + (pos *
(MAX(dd->dd_CurrentY,dd->dd_MaxY-(oldWin->Height-YOFF-9L))
- MIN(dd->dd_CurrentY, dd->dd_MinY)) ) / MAXBODY;
break;
}
resize(oldWin);
SetRast(oldWin->RPort, 0L);
refresh(oldWin);
}
/* Recalculate the size of a window's virtual coord system */
resize(w) struct Window *w; {
struct Node *node;
struct MyWBObject *obj;
struct MyDrawerData *dd;
long effH, effW, total, left, right, pot, body;
obj = (struct MyWBObject *)w->UserData;
dd = obj->wo_DrawerData;
dd->dd_MinX = dd->dd_MinY = 10000;
dd->dd_MaxX = dd->dd_MaxY = -10000;
/* For each icon living in the window.. */
for (node=dd->dd_Children.lh_Head; node->ln_Succ;
node=node->ln_Succ) {
obj = OBJ(node,CHILD);
if (obj->wo_IconWin!=w) continue;
/* Each icon contains two pieces..a title and an image */
/* Take the MIN of the left edges.. */
dd->dd_MinX = MIN(dd->dd_MinX,
obj->wo_CurrentX + obj->wo_NameXOffset);
/* and the MAX of the right edges */
right = MAX(obj->wo_Gadget.Width,
obj->wo_NameXOffset + 8*strlen(obj->wo_Name));
dd->dd_MaxX = MAX(dd->dd_MaxX, obj->wo_CurrentX + right);
/* Likewise top and bottom edges */
dd->dd_MinY = MIN(dd->dd_MinY, obj->wo_CurrentY);
dd->dd_MaxY = MAX(dd->dd_MaxY, obj->wo_CurrentY +
obj->wo_Gadget.Height + 10L);
}
/* Now recalculate the horizontal extent... */
/* total: Total size of virtual coord system */
/* left: Size undisplayed to left */
/* right: Size undisplayed to right */
effW = w->Width-14L;
total = MAX(dd->dd_CurrentX + effW, dd->dd_MaxX)
- MIN(dd->dd_CurrentX, dd->dd_MinX);
left = MAX(dd->dd_CurrentX - dd->dd_MinX, 0L);
right = total - left - effW;
if ((left + right)==0L) pot = 0L;
else pot = (MAXBODY * left) / (left + right);
body = (MAXBODY * effW) / total;
ModifyProp(&dd->dd_HorizScroll, w, NULL, FREEHORIZ | AUTOKNOB,
pot, MAXBODY, body, MAXBODY);
/* and the vertical extent */
effH = w->Height-YOFF-9L;
total = MAX(dd->dd_CurrentY + effH, dd->dd_MaxY)
- MIN(dd->dd_CurrentY, dd->dd_MinY);
left = MAX(dd->dd_CurrentY - dd->dd_MinY, 0L);
right = total - left - effH;
if ((left + right)==0L) pot = 0L;
else pot = (MAXBODY * left) / (left + right);
body = (MAXBODY * effH) / total;
ModifyProp(&dd->dd_VertScroll, w, NULL, FREEVERT | AUTOKNOB,
MAXBODY, pot, MAXBODY, body);
}
/* Must do this each time a window's size is changed */
/* To prevent drawing over the borders */
reclip(w) struct Window *w; {
struct Region *reg, *oldreg;
reg = NewRegion();
rect.MaxX = w->Width - 19;
rect.MaxY = w->Height - 11;
OrRectRegion(reg, &rect);
oldreg = InstallClipRegion(w->WLayer, reg);
if (oldreg) DisposeRegion(oldreg);
}
BPTR getlock(obj) struct MyWBObject *obj; {
BPTR lock;
char name[31];
/* Either the obj's own Lock, or the Lock of the drawer it's in,
or manufacture a new one */
lock = obj->wo_Lock;
if (!lock) if (obj->wo_Parent)
lock = obj->wo_Parent->wo_DrawerData->dd_Lock;
if (!lock) { /* Presumably a disk */
if (debug) printf("%lx <%s> (a %s) needs a new lock\n",
obj, obj->wo_Name, type[obj->wo_Type]);
strcpy(name, obj->wo_Name);
strcat(name,":");
lock = obj->wo_Lock = Lock(name, ACCESS_READ);
/* Maybe user refused to reinsert disk */
if (!lock) printf("Can't lock <%s>\n", name);
if (debug) printf("getlock: new lock: %lx\n",lock);
}
return lock;
}
struct DeviceList *vol(lock) BPTR lock; {
struct FileLock *fl;
/* Return the Volume corresponding to a given Lock */
if (!lock) {printf("vol: Null lock\n"); return NULL;}
fl = (struct FileLock *)BADDR(lock);
return (struct DeviceList *)BADDR(fl->fl_Volume);
}
/* Convert a BSTR to a C string */
bs2cs(buf, bstr) char *buf; BPTR bstr; {
char *p;
p = (char *)BADDR(bstr);
strncpy(buf, p+1, *p);
buf[*p] = 0;
}
/* C string to BSTR - (buf must be Long Aligned) */
cs2bs(buf, s) char *buf, *s; {
strcpy(buf+1, s);
*buf = strlen(s);
}
renpkt(l1, n1, l2, n2) BPTR l1, l2; char *n1, *n2; {
long arg[4], res;
struct DeviceList *dl1, *dl2;
char *buf1, *buf2;
struct MsgPort *handid;
if (debug) printf("Renpkt: <%s> to <%s>\n", n1, n2);
if (!l1 || !l2) {printf("renpkt error: null lock\n"); return;}
if ((dl1=vol(l1)) != (dl2=vol(l2)))
{printf("renpkt error: different volumes\n"); return;}
handid = ((struct FileLock *)BADDR(l1))->fl_Task;
/* Must be long aligned: */
buf1 = AllocMem(31L, MEMF_CPC); buf2 = AllocMem(31L, MEMF_CPC);
cs2bs(buf1, n1); cs2bs(buf2, n2);
arg[0] = l1; arg[2] = l2;
arg[1] = ((long)buf1)>>2; arg[3] = ((long)buf2)>>2;
if (!sendpkt(handid, ACTION_RENAME_OBJECT, arg, 4L))
printf("Rename failed\n");
FreeMem(buf1, 31L); FreeMem(buf2, 31L);
}
renBoth(l1, n1, l2, n2) BPTR l1, l2; char *n1, *n2; {
/* Rename both the file and its .info file */
renpkt(l1, n1, l2, n2);
*rindex(n1,'.') = 0; *rindex(n2,'.') = 0;
renpkt(l1, n1, l2, n2);
}
long tooSoon() {
long dt;
dt = upSecs - downSecs;
if (dt>1) return FALSE;
dt = upMicros - downMicros + 1000000L*dt;
return (dt<200000L);
/* Two-tenths of a sec between selup and seldown
is too soon to count as a drag operation */
}